Memory manager BORLNDMM.DLL, padajici program pri uvolneni DLL na Win95

Otázka od: Radek Kučera

24. 9. 2002 13:41

Win2000, Delphi6, MSSQL2000, Adonis

    Dobry den,
v programu pouzivam volani DLL. Pri uvolneni DLL ( FreeLibrary(LibHandle) )
na OS WIN95 vyskoci chyba: "Program provedl neplatnou operaci a bude
ukoncen".
Na Win98, Win2000 i WinXP to funguje spravne.

I na W2000 me program padal v runtime modu (z vyvojoveho prostredi
fungoval), pokud jsem pouzival BORLNDMM.DLL : verze: 6.0.6.163 velikost:
22016 z 22.5.2001 8:00 z Delphi6. Kdyz jsem ji nahradil: BORLNDMM.DLL :
verze: 5.0.12.34 velikost: 13312 z 31.1.2000 5:00, funguje program spravne.

Na Win95 pada, i kdyz jsem zkusil BORLNDMM.DLL z Delphi4, ci pridal
DELPHIMM.DLL z Delphi4.
Muzete mne nekdo poradit, jak vyresit problem uvolneni DLL na Win95 ?

Prikladam ukazku pouziti:

procedure _SpustModul(...);
var
  LIBHandle:THandle;
  Run:TRun;
  DataRun:TDLL;
  HandleRun:THandle;
  NazevDLL:string;
  FceDLL :string;
  Modul : String;
begin
  FceDll :='RunDllDetail';
  HandleRun:=Application.Handle;
//Spuštění vybraného modulu(dll souboru)
  LibHandle:=0;
  @Run:=nil;
  try
    LibHandle:=Loadlibrary(PChar(NazevDLL));
    @Run:=GetProcAddress(LibHandle,PChar(FceDll));
    if not (@Run=nil) then
  finally
    if LibHandle <> 0 then
    begin
      FreeLibrary(LibHandle); //!!! A tady to pada na Win95 !!!
    end;
  end;
end;

    Predem dekuji za odpovedi

                     Radek Kucera


Odpovedá: Petr Vones

24. 9. 2002 18:17

         Win95
From: "Radek Kučera" <raku@foresta.cz>
> I na W2000 me program padal v runtime modu (z vyvojoveho prostredi
> fungoval), pokud jsem pouzival BORLNDMM.DLL : verze: 6.0.6.163 velikost:

Co to napsat tak aby pouziti BORLNDMM.DLL nebylo vubec nutne.

Petr Vones

Odpovedá: Dalibor Toman

24. 9. 2002 15:37

         Win95
> FreeLibrary(LibHandle); //!!! A tady to pada na Win95 !!!

1) nez pouzivat manazer pameti pro sdileni pameti s DLLkem je asi
lepsi to DLL napsat tak, aby jej nepoutrebovalo (cili nikdy
neuvolnovat procesem pamet alokovanou DLLkem a naopak)
2) pokud pouzivas COMy v DLL pak za urcitych podminek to bude v
FreeLibrary padat taky

D. Toman


Odpovedá: Radek Kučera

25. 9. 2002 10:39

         Win95

> Co to napsat tak aby pouziti BORLNDMM.DLL nebylo vubec nutne.
>

Myslim si, ze pouziti BORLNDMM.DLL je nutne, nebot v predanych parametrech
do DLL je typ "packed record" se stringy.

Mirne doplnena procedura o dalsi kus zdroje, ktery jsem v minulem mailu pro
prehlednost vynechal:

type
// definice pro predavana data
  TDLL = packed record
     Database:TAdoDataBase;
     Zkratka : String;
     UO : String;
     Regcis:Integer;
     DT_Hlavni:String;
     DT:String;
     Poradi:Integer;
     ModPrace:Char;
     navrat:Integer;
  end;
// funkce pro komunikaci mazi master a DLL
  TRUN = function(AHandle:THandle;var DLL:TDLL):Boolean;stdcall;
  TF_DLL = class(TForm)
    ADODatabaseParadox: TADODatabase;
    MasterDataBase: TADODatabase;
    procedure FormCreate(Sender: TObject);
  end;


procedure _SpustModul(...);
var
  LIBHandle:THandle;
  Run:TRun;
  DataRun:TDLL;
  HandleRun:THandle;
  NazevDLL:string;
  FceDLL :string;
  Modul : String;
begin
  FceDll :='RunDllDetail';
// naplneni predavanych parametru
  application.createform(tF_DLL,F_DLL);
  DataRun.Database := F_DataModule.ADODatabase;
  DataRun.UO :=
Trim(F_DataModule.ADODS_Zadost.FieldByName('UO').AsString);
  DataRun.RegCis :=
F_DataModule.ADODS_Zadost.FieldByName('RegCis').AsInteger;
  DataRun.DT_hlavni :=
F_DataModule.ADODS_Zadost.FieldByName('DT_hlavni').AsString;
  DataRun.Zkratka := Copy(F_UvodniFormular.G_Zkratka,1,10) {'JDB'};
  DataRun.ModPrace := ModPrace;
// naplneni handlu z duvodu ukonveni master aplikace
  HandleRun:=Application.Handle;
//Spusteni vybraneho modulu(dll souboru)
  LibHandle:=0;
  @Run:=nil;
  try
    LibHandle:=Loadlibrary(PChar(NazevDLL));
    @Run:=GetProcAddress(LibHandle,PChar(FceDll));
    if not (@Run=nil) then
  finally
    if LibHandle <> 0 then
    begin
      FreeLibrary(LibHandle); //!!! A tady to pada na Win95 !!!
    end;
  end;
end;

    Predem dekuji za rady,

            Radek Kucera


Odpovedá: Dalibor Toman

25. 9. 2002 13:39

         Win95
> > Co to napsat tak aby pouziti BORLNDMM.DLL nebylo vubec nutne.
> >
>
> Myslim si, ze pouziti BORLNDMM.DLL je nutne, nebot v predanych
parametrech
> do DLL je typ "packed record" se stringy.

samozrejme je nutne podobne cunarny eliminovat - staci zajistit, ze v
predanych paremetrech (dynamicky alokovanych castech) nebudou
provadeny zmeny.

> Mirne doplnena procedura o dalsi kus zdroje, ktery jsem v minulem
mailu pro
> prehlednost vynechal:
>
> type
> // definice pro predavana data
> TDLL = packed record
> Database:TAdoDataBase;
> Zkratka : String;
> UO : String;
> Regcis:Integer;
> DT_Hlavni:String;
> DT:String;
> Poradi:Integer;
> ModPrace:Char;
> navrat:Integer;
> end;

urcite by AnsiStringa sla nahradit napriklad ShortStringy nebo PChar
buffery (array[0..x] of char). I v Databazi mas zrejme definovanou max
delku uvedenych retezcu - cili neni problem nahjradit AnsiString.
Pokud se AnsiStringu nechces/nemuzes vzdat pak je nutn zajistit, ze
pametove operace pro ne budou probihat vzdy bud v DLL nebo v aplikaci.
Napriklad ma-li DLL naplnit stringa, pak je musi aplikace pouzivat
jako readonly a po te co je uz nepotrebuje by se mela zavolat funkce z
DLL, ktera ansistringa dealokuje (xy.Zkratka := '')

D. Toman